package com.ruoyi.system.listener;

import com.alibaba.fastjson2.JSON;
import com.rabbitmq.client.Channel;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.config.RabbitMQConfig;
import com.ruoyi.system.domain.vo.MessageVO;
import com.ruoyi.system.service.IMessageService;
import com.ruoyi.system.vo.RabbitMQInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@Slf4j
public class CacheSyncDBListener {

    @Autowired
    private IMessageService messageService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 监听指定队列，接收消息
     * @param messageStr 消息内容
     */
    @RabbitListener(queues = RabbitMQConfig.CACHE_SYNC_DB_QUEUE)
    public void receiveMessage(String  messageStr, Channel channel, Message message) throws IOException {
        try {
            RabbitMQInfoVO rabbitMQInfoVO = JSON.parseObject(messageStr, RabbitMQInfoVO.class);
            log.info("CacheSyncDBListener receiveMessage：{}" , rabbitMQInfoVO);

//            CorrelationData correlationData = new CorrelationData();
//            correlationData.setId(messageVO.getId());

            // TODO 处理消息的业务逻辑
            handleMq(rabbitMQInfoVO);


            // 手动确认消息
            // 第二个参数multiple: true表示确认所有消息直到当前消息，false表示只确认当前消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.info("消息确认成功，消息ID: " + message.getMessageProperties().getMessageId());
        } catch (IOException e) {
            log.error("消息确认失败，消息ID: " + message.getMessageProperties().getMessageId());
            log.error("消息确认失败，消息内容: {}",e.getMessage() );

            // 处理失败时的策略
            if (message.getMessageProperties().getRedelivered()) {
                // 消息已经重试过一次，直接拒绝并丢弃
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                log.error("消息处理失败，消息ID: " + message.getMessageProperties().getMessageId());
            } else {
                // 消息第一次处理失败，重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                log.error("消息处理失败,重新入队，消息ID: " + message.getMessageProperties().getMessageId());
            }
        }
    }

    /**
     * 处理消息接口   TODO 待验证
     * @param rabbitMQInfoVO
     */
    private void handleMq(RabbitMQInfoVO rabbitMQInfoVO) {
        switch (rabbitMQInfoVO.getOpsFlag()) {
            case 1:

                // 异步删除 同步接口传来的redis key
                redisCache.removeBatchKeys(rabbitMQInfoVO.getAllUserSessionMsgKeys());
                redisCache.removeBatchKeys(rabbitMQInfoVO.getMessageIdKeySet());

                break;
            default:
                break;
        }
    }

}
